package com.miraclesea.module.rbac.vo;

public final class PermissionUtil {
	
	private static final String ENUM_SPEERATOR = "#";
	
	private PermissionUtil() { }
	
	public static Permission from(final String permissionName) {
		int seperatorIndex = getSeperatorIndex(permissionName);
		String className = permissionName.substring(0, seperatorIndex);
		String enumName = permissionName.substring(seperatorIndex + 1);
		return getPermission(permissionName,  getEnumClass(permissionName, className), enumName);
	}
	
	private static int getSeperatorIndex(final String permissionName) {
		int result = permissionName.indexOf(ENUM_SPEERATOR);
		if (result < 1) {
			throw new IllegalArgumentException(String.format(
					"Permission Name '%s' invalid, should be full class name %s enum instance. Example: com.miracle.test.TestPermission#Test1", 
					permissionName, ENUM_SPEERATOR));
		}
		return result;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Class<Enum> getEnumClass(final String permissionName, final String className) {
		Class<Enum> result;
		try {
			result = (Class<Enum>) Class.forName(className);
		} catch (final ClassNotFoundException ex) {
			throw new IllegalArgumentException(String.format("Not found, permission name is '%s', parsed class is '%s'", permissionName, className));
		}
		if (!result.isEnum()) {
			throw new IllegalArgumentException(String.format("Not a enum, permission name is '%s', parsed class is '%s'", permissionName, className));
		}
		return result;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Permission getPermission(final String permissionName, final Class<Enum> clazz, final String enumName) {
		Enum result = Enum.valueOf(clazz, enumName);
		if (!(result instanceof Permission)) {
			throw new IllegalArgumentException(String.format("Not a permission, permission name is '%s', parsed class is '%s'", permissionName, clazz.getName()));
		}
		return (Permission) result;
	}
	
	public static String toPermissionString(final Permission permission) {
		return new StringBuilder().append(permission.getClass().getName()).append(ENUM_SPEERATOR).append(permission).toString();
	}
}
